﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Widgetsphere.Generator.Models;
using Gravitybox.Controls.Wizard;

namespace Widgetsphere.Generator.Forms
{
	public partial class ImportStaticDataForm : Form
	{
		#region Class Members

		private Table _currentTable = null;

		#endregion

		#region Constructors

		public ImportStaticDataForm()
		{
			InitializeComponent();

			wizard1.BeforeSwitchPages += new Gravitybox.Controls.Wizard.Wizard.BeforeSwitchPagesEventHandler(wizard1_BeforeSwitchPages);
			wizard1.AfterSwitchPages += new Gravitybox.Controls.Wizard.Wizard.AfterSwitchPagesEventHandler(wizard1_AfterSwitchPages);
			wizard1.Finish += new EventHandler(wizard1_Finish);
			wizard1.FinishEnabled = false;
			DatabaseConnectionControl1.LoadSettings();

		}

		public ImportStaticDataForm(Table currentTable)
			: this()
		{
			_currentTable = currentTable;
			lblWelcome.Text = "This wizard will walk you through the process of import static data from an existing database table. The database table schema must match the target table '" + currentTable.Name + "' in the model.";
		}

		#endregion

		#region Methods

		private void LoadData(DataTable dt)
		{
			this.dataGridView1.Columns.Clear();			
			this.dataGridView1.DataSource = dt;
		}

		#endregion

		#region Event Handlers

		private void wizard1_Finish(object sender, EventArgs e)
		{
			DatabaseConnectionControl1.PersistSettings();
			
			_currentTable.StaticData.Clear();
			System.Data.DataTable dt = (System.Data.DataTable)this.dataGridView1.DataSource;
			foreach (System.Data.DataRow dr in dt.Rows)
			{
				RowEntry rowEntry = new RowEntry(_currentTable.Root);
				for (int ii = 0; ii < _currentTable.Columns.Count; ii++)
				{
					CellEntry cellEntry = new CellEntry(_currentTable.Root);
					cellEntry.ColumnRef = _currentTable.Columns[ii];
					//if (dr[ii].GetType().ToString() == "System.Byte[]")
					//{
					//  cellEntry.Value = System.Text.ASCIIEncoding.ASCII.GetString((byte[])dr[ii]);
					//}
					//else
					//{
						cellEntry.Value = dr[ii].ToString();
					//}
					rowEntry.CellEntries.Add(cellEntry);
				}
				_currentTable.StaticData.Add(rowEntry);
			}

			this.DialogResult = DialogResult.OK;
			this.Close();
		}

		private void wizard1_AfterSwitchPages(object sender, Gravitybox.Controls.Wizard.Wizard.AfterSwitchPagesEventArgs e)
		{
			WizardPage oldPage = wizard1.WizardPages[e.OldIndex];
			WizardPage newPage = wizard1.WizardPages[e.NewIndex];

			wizard1.FinishEnabled = (newPage == pageSummary);

		}

		private void wizard1_BeforeSwitchPages(object sender, Gravitybox.Controls.Wizard.Wizard.BeforeSwitchPagesEventArgs e)
		{
			WizardPage oldPage = wizard1.WizardPages[e.OldIndex];
			WizardPage newPage = wizard1.WizardPages[e.NewIndex];

			if ((oldPage == pageImport) && (e.NewIndex > e.OldIndex))
			{
				//Test Connection
				string connectString = DatabaseConnectionControl1.ImportOptions.GetConnectionString();
				bool valid = DatabaseHelper.TestConnectionString(connectString);
				if (!valid)
				{
					MessageBox.Show("The information does not describe a valid connection string.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
					e.Cancel = true;
					return;
				}

				//Load the dropdown
				cboTable.DataSource = SqlSchemaToModel.GetTableListFromDatabase(connectString);
				cboTable.SelectedItem = _currentTable.Name;

			}
			else if ((oldPage == pageChooseTable) && (e.NewIndex > e.OldIndex))
			{
				//Verify that the table schema matches
				string connectString = DatabaseConnectionControl1.ImportOptions.GetConnectionString();
				IEnumerable<Column> columnList = SqlSchemaToModel.GetTableDefinitionFromDatabase(connectString, (string)cboTable.SelectedValue, (ModelRoot)_currentTable.Root);

				if (columnList.Count() != _currentTable.Columns.Count)
				{
					MessageBox.Show("The tables do not have the same number of columns. The database table schema must match the model table.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
					e.Cancel = true;
					return;
				}

				foreach (Column column in columnList.OrderBy(x => x.Name))
				{
					if (_currentTable.Columns.FindByName(column.Name) == null)
					{
						MessageBox.Show("The column '" + column.Name + "' exists in the database table but not in the model table. The database table schema must match the model table.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
						e.Cancel = true;
						return;
					}
				}

				//Load the static data grid				
				StringBuilder sb = new StringBuilder();
				sb.Append("SELECT ");	
				foreach (Reference reference in _currentTable.Columns)
				{
					Column column = (Column)reference.Object;
					if (column.IsBinaryType) sb.Append("NULL");
					else sb.Append("[" + column.Name + "]");
					if (_currentTable.Columns.IndexOf(reference) < _currentTable.Columns.Count - 1)
						sb.Append(", ");
				}				
				sb.AppendLine(" FROM [" + _currentTable.Name + "]");
				DataSet ds = DatabaseHelper.ExecuteDataset(connectString, sb.ToString());
				this.LoadData(ds.Tables[0]);

			}

		}

		#endregion

	}
}
